package org.dbstar.scheduler.control.db.conf;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dbstar.scheduler.beans.JobConf;
import org.dbstar.scheduler.control.JobConfController;
import org.dbstar.scheduler.control.db.JdbcTemplateDao;
import org.dbstar.scheduler.control.exception.DaoException;
import org.dbstar.scheduler.identifier.Identifier;
import org.dbstar.scheduler.identifier.IdentifierFactory;
import org.dbstar.scheduler.identifier.IdentifierType;
import org.springframework.jdbc.core.JdbcTemplate;


/**
 * 使用JdbcTemplate的JobConfController实现类。
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-4-23
 */
public class JdbcTemplateJobConfController extends JdbcTemplateDao implements JobConfController {
	private final IdentifierFactory factory;
	private final JobConfQuery queryAll;
	private final JobConfQueryByCatalog queryByCatalog;
	private final JobConfQueryByIdentifier queryByIdentifier;
	private final JobConfInsert insert;
	private final JobConfUpdate update;
	private final JobConfUpdateAverageRunTime updateAverageRunTime;
	private final JobConfMove move;
	private final JobConfDelete delete;

	public JdbcTemplateJobConfController(JdbcTemplate jt, IdentifierFactory factory) {
		super(jt);
		this.factory = factory;
		this.queryAll = new JobConfQuery(jt, "ORDER BY CATALOG, SYSTEM_IDENTIFIER, SEQUENCE");
		this.queryByCatalog = new JobConfQueryByCatalog(jt);
		this.queryByIdentifier = new JobConfQueryByIdentifier(jt);
		this.insert = new JobConfInsert(jt);
		this.update = new JobConfUpdate(jt);
		this.updateAverageRunTime = new JobConfUpdateAverageRunTime(jt);
		this.move = new JobConfMove(jt);
		this.delete = new JobConfDelete(jt);
	}

	@Override
	public List<JobConf> getAllJobConfs() throws DaoException {
		try {
			return queryAll.execute();
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public List<JobConf> getJobConfs(int catalogId) throws DaoException {
		try {
			return queryByCatalog.execute(catalogId);
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public JobConf getJobConf(Identifier identifier) throws DaoException {
		checkIdentifier(identifier);
		try {
			return queryByIdentifier.findObject(identifier.getSystemIdentifier(), identifier.getSequence());
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	private void checkJobConf(JobConf conf, boolean update) throws DaoException {
		if (StringUtils.isBlank(conf.getName())) {
			throw new DaoException("Job Configuration's name can not blank.");
		}
		if (update) {
			if (conf.getIdentifier() == null) {
				throw new DaoException("Job Configuration's Identifier must set.");
			}
		}
	}

	private void checkIdentifier(Identifier identifier) throws DaoException {
		if (identifier == null) {
			throw new DaoException("Identifier must not null.");
		}
		if (identifier.getIdentifierType() != IdentifierType.conf) {
			throw new DaoException("Identifier not a Job Configuration identifier: " + identifier.getStringIdentifier());
		}
	}

	@Override
	public Identifier addJobConf(JobConf jobConf) throws DaoException {
		checkJobConf(jobConf, false);
		try {
			Identifier identifier = factory.createIdentifier(IdentifierType.conf);
			insert.insertJobConf(jobConf, identifier);
			jobConf.setIdentifier(identifier);
			jobConf.setModifyTime(null);
			return identifier;
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void updateJobConf(JobConf jobConf) throws DaoException {
		checkJobConf(jobConf, true);
		try {
			if (update.updateJobConf(jobConf) == 0) {
				throw new IllegalArgumentException("Job Configuration not exist for update: "
						+ jobConf.getIdentifier().getStringIdentifier());
			}
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void updateJobConfAverageRunTime(Identifier identifier, int averageRunTime) throws DaoException {
		checkIdentifier(identifier);
		try {
			if (updateAverageRunTime.updateJobConf(identifier, averageRunTime) == 0) {
				throw new IllegalArgumentException("Job Configuration not exist for update: "
						+ identifier.getStringIdentifier());
			}
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void moveJobConf(Identifier identifier, int catalog) throws DaoException {
		checkIdentifier(identifier);
		try {
			if (move.moveJobConf(identifier, catalog) == 0) {
				throw new IllegalArgumentException("Job Configuration not exist for move: "
						+ identifier.getStringIdentifier());
			}
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void removeJobConf(Identifier identifier) throws DaoException {
		checkIdentifier(identifier);
		try {
			if (delete.update(identifier.getSystemIdentifier(), identifier.getSequence()) == 0) {
				throw new IllegalArgumentException("Job Configuration not exist for delete: "
						+ identifier.getStringIdentifier());
			}
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}
}
